/*
 * Copyright 2009 Zero Separation
 *
 *     This file is part of PDSUtilities.
 *
 *  PDSUtilities is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  PDSUtilities is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with PDSUtilities.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

package com.zero_separation.pds.utilities.referencecollections;

import com.sun.sgs.app.AppContext;
import com.sun.sgs.app.ManagedObject;
import com.sun.sgs.app.ManagedReference;
import java.util.ListIterator;

/**
 * This class provides an iterator over a reference list. Please note that the current
 * implementation is not guaranteed serializable and will only work correctly within a
 * single darkstar transaction or when part of the same managed object as the containing
 * collection. It cannot be persisted to the datastore as part of a separate managed
 * object.
 *
 * @author Tim Boura - Zero Separation
 */
public class ReferenceListIterator<T> extends ReferenceIterator<T> implements ListIterator<T> {

    /** The version of the serialized form of this class. */
    private static final long serialVersionUID = 1L;

    private ListIterator<Object> internalIterator;

    ReferenceListIterator(ListIterator<Object> internalIterator) {
        super(internalIterator);
        this.internalIterator = internalIterator;
    }

    public boolean hasPrevious() {
        return internalIterator.hasPrevious();
    }

    public T previous() {
        Object o = internalIterator.previous();
        if (o instanceof ManagedReference)
            return ((ManagedReference<T>)o).get();
        else
            return (T) o;
    }

    public int nextIndex() {
        return internalIterator.nextIndex();
    }

    public int previousIndex() {
        return internalIterator.previousIndex();
    }

    public void set(T e) {
        if (e instanceof ManagedReference)
            throw new IllegalArgumentException("Cannot insert a managed reference into a ReferenceList");

        if (e instanceof ManagedObject)
            internalIterator.set(AppContext.getDataManager().createReference(e));
        else
            internalIterator.set(e);
    }

    public void add(T e) {
        if (e instanceof ManagedReference)
            throw new IllegalArgumentException("Cannot insert a managed reference into a ReferenceList");
        
        if (e instanceof ManagedObject)
            internalIterator.add(AppContext.getDataManager().createReference(e));
        else
            internalIterator.add(e);
    }

}

